package org.carota.itext5;

import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.*;
import org.carota.pdf.PdfProcessor;
import org.carota.util.RelateUtil;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author : AnWen
 * @version :1.0
 * @since : 2023-03-31 17:22
 */
@Slf4j
@NoArgsConstructor
public class FillDocxTemplateConfigurer extends FillPdfTemplateConfigurer {

    public static final Pattern PATTERN = Pattern.compile ("\\$\\{([^}]*)}");


    public FillDocxTemplateConfigurer(PdfProcessor processor) {
        super (processor);
    }

    /**
     * 执行PDF操作
     */
    @Override
    public void execute() {

        String templatePath = processor.getTemplatePath ();
        ByteArrayOutputStream bos = processor.getBos ();

        try (InputStream inputStream = RelateUtil.getInputStream (templatePath)) {
            XWPFDocument docx = new XWPFDocument (inputStream);
            paragraphReplace (docx.getParagraphs (), getData ());
            tableReplace(docx.getTables(), getData ());
            PdfOptions options = PdfOptions.create ();
            PdfConverter.getInstance ().convert (docx, bos, options);
        } catch (Exception e) {
            e.printStackTrace ();
            log.error ("文件转化异常:", e);
        }

    }


    private void tableReplace(List<XWPFTable> tables, Map<String, Object> params) {
        for (XWPFTable table : tables) {
            for (int i = 0; i < table.getNumberOfRows (); i++) {
                XWPFTableRow row = table.getRow (i);
                for (int j = 0; j < row.getTableCells ().size (); j++) {
                    XWPFTableCell cell = row.getCell (j);
                    paragraphReplace (cell.getParagraphs (), params);
                }
            }
        }
    }



    private void paragraphReplace(List<XWPFParagraph> paragraphs, Map<String, Object> params) {
        for (XWPFParagraph p : paragraphs) {
            for (XWPFRun r : p.getRuns ()) {
                String content = r.getText (r.getTextPosition ());
                if (StringUtils.isNotBlank (content)) {
                    Matcher matcher = PATTERN.matcher (content);
                        StringBuffer replacedString = new StringBuffer ();
                        while (matcher.find ()) {
                            String variable = matcher.group (1);
                            String replacement = params.getOrDefault (variable, "").toString ();
                            matcher.appendReplacement (replacedString, replacement);
                        }
                        matcher.appendTail (replacedString);
                        r.setText (replacedString.toString (), 0);
                }
            }
        }
    }


    /**
     * 校验参数
     */
    @Override
    protected void checkParams() {
        checkParams ("word模板填充", getData (), "data");
    }


    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE;
    }
}
